#toleranceTotal <- 2000
#m <- c(2,6.5,8.1,2.985,0,0,0.1625,12.0965,0,-2,-0.1175,-24.2,-5.5)
#s <- c(0.005,0.005,0.006,0.005,0.01167,0.01167,0.00417,0.007,0.01433,0.005,0.00417,0.00867,0.007)
#n <- 20
#LSL <- -0.04
#USL <- 0.04
#t <- "Test"
#path <- "D:/1.png"

library(ggplot2)

tolerance.SingleRandom <- function(mean,sd) {
    len <- length(mean)
    n <- rep(1,len)
    return(rnorm(n, mean, sd))
}

tolerance.AllRandom <- function(N = 2000, mean, sd) {
    return(t(replicate(N, tolerance.SingleRandom(mean, sd))))
}

tolerance.Sum <- function(itemData) {
    if (dim(itemData)[1] == 1) return(itemData)
    L <- apply(itemData, 1, sum)
    return(L)
}

tolerance.getBasicData <- function(itemData) {
    avgValue <- mean(itemData)
    minValue <- min(itemData)
    maxValue <- max(itemData)
    stdevValue <- sd(itemData)
    if (is.na(stdevValue)) stdevValue <- sum(s)
    rangeValue <- maxValue - minValue
    CL <- avgValue + stdevValue*c(-3, -2, -1, 0, 1, 2, 3)

    d <- data.frame(avg=avgValue, min=minValue, max=maxValue, sd=stdevValue, range=rangeValue, ucl=CL[1], sm2=CL[2], sm1=CL[3], sp1=CL[5], sp2=CL[6], lcl=CL[7])

    dlist <- list(d=d, cl=CL)
    return(dlist)
}

tolerance.buildBar <- function(itemData) {
    tryCatch({
        basicData <- tolerance.getBasicData(itemData)
        sx <- sort(itemData)
        bd <- basicData$d
        CL <- basicData$cl

        curveXValue <- sort(c(sx, CL))
        xlength <- length(curveXValue)
        nd <- data.frame(d=curveXValue)
        idx <- nd$d %in% CL
        nd$d[idx] <- NA
        ry <- dnorm(curveXValue, mean(curveXValue), sd(curveXValue))

        centerx <- rep(bd$avg, times=xlength)
        sigm_m1 <- rep(bd$sm1, times=xlength)
        sigm_m2 <- rep(bd$sm2, times=xlength)
        sigm_p1 <- rep(bd$sp1, times=xlength)
        sigm_p2 <- rep(bd$sp2, times=xlength)
        ucl <- rep(bd$ucl, times=xlength)
        lcl <- rep(bd$lcl, times=xlength)

        dv <- round(seq(bd$min, bd$max, by=(bd$max - bd$min)/15),6)
        dv1 <- seq(bd$min, bd$max, by=(bd$max - bd$min)/n)
        barValue <- c(0, as.data.frame(table(cut(sx, dv1, inclue.lowest=T)))[,2])

        yMax <- abs(max(barValue) * 1.1)
        liney <- seq(0, yMax, length=xlength)
        dig <- max(barValue)/max(ry)

        dc <- data.frame(x=nd$d, rx=curveXValue, y=ry, cx=centerx, cy=liney)
        binsize <- (bd$max - bd$min)/n

        p <- ggplot(dc, aes(x=x))
        p <- p + geom_line(aes(x=cx, y=liney), colour="#568A89") + annotate("text", x=CL[4], y=yMax, label="C", size=2.5, hjust=.5, vjust=-.2, colour="#568A89")
        p <- p + geom_line(aes(x=sigm_p1, y=liney), colour="#71843F") + annotate("text", x=CL[5], y=yMax, label="s", size=2.5, hjust=.5, vjust=-.2, colour="#71843F")
        p <- p + geom_line(aes(x=sigm_m1, y=liney), colour="#71843F") + annotate("text", x=CL[3], y=yMax, label="-s", size=2.5, hjust=.5, vjust=-.2, colour="#71843F")
        p <- p + geom_line(aes(x=sigm_m2, y=liney), colour="#71843F") + annotate("text", x=CL[2], y=yMax, label="-2s", size=2.5, hjust=.5, vjust=-.2, colour="#71843F")
        p <- p + geom_line(aes(x=sigm_p2, y=liney), colour="#71843F") + annotate("text", x=CL[6], y=yMax, label="2s", size=2.5, hjust=.5, vjust=-.2, colour="#71843F")
        p <- p + geom_line(aes(x=ucl, y=liney), colour="brown") + annotate("text", x=CL[7], y=yMax, label="UCL", size=2.5, hjust=.5, vjust=-.2, colour="brown")
        p <- p + geom_line(aes(x=lcl, y=liney), colour="brown") + annotate("text", x=CL[1], y=yMax, label="LCL", size=2.5, hjust=.5, vjust=-.2, colour="brown")
        p <- p + geom_histogram(aes(x=x), na.rm=FALSE, binwidth=binsize, fill="#305d8c", colour="white",origin=basicData$d$min, alpha=0.9)
        #p <- p + geom_histogram(na.rm=FALSE, binwidth = binsize, fill="#305d8c", colour="white", alpha=0.9)
        p <- p + geom_line(aes(x=rx, y=y*dig), colour="red")
        p <- p + geom_line(aes(x=LSL, y=liney), colour="red") + annotate("text", x=LSL, y=yMax, label="LSL", size=2.5, hjust=.5, vjust=-.2, colour="red")
        p <- p + geom_line(aes(x=USL, y=liney), colour="red") + annotate("text", x=USL, y=yMax, label="USL", size=2.5, hjust=.5, vjust=-.2, colour="red")
        p <- p + scale_x_continuous(breaks=dv, labels=dv)
        p <- p + theme(axis.text.x=element_text(angle=30, size=10, hjust=1, vjust=1))
        p <- p + xlab("")
        p <- p + ylab("Count")
        p <- p + ggtitle(t)
        return(p)

    }, error=function(e) {
        dc <- data.frame(x=c(1:10))
        p3 <- ggplot(dc) + geom_line(aes(x=0, y=0), colour="red") + ggtitle(t)
        p3 <- p3 + annotate("text", x=0, y=0, label="This item can not be built to a chart.", size=4.5, hjust=.5, vjust=-.2)
        return(p3)
    })
}

tolerance.buildCharts <- function(itemData, path) {
    if (!is.null(path)) {
        png(path, width = 800, height=500)
        print(tolerance.buildBar(itemData))
        dev.off()
    }
}

if (is.null(toleranceTotal) || toleranceTotal == 0) {
    toleranceTotal <- 2000
}

if (is.nan(USL)) USL <- Inf
if (is.nan(LSL)) LSL <- -Inf

toleranceRandomData <- tolerance.AllRandom(toleranceTotal, m, s)
toleranceRandomTData <- t(toleranceRandomData)
x <- tolerance.Sum(toleranceRandomData)
tolerancePassNum <- sum(x >= LSL & x <= USL)
toleranceResult <- tolerancePassNum/length(x)

if (is.null(x)) {
    print("No data for building")
}

if (is.null(t)) {
    t <- "Test Item"
}

if (is.null(n) || n==0) {
    n <- ceiling(toleranceTotal)
}

tolerance.buildCharts(x, path)